package com.example.thread;

// 二、下面这个例子是，在一个线程中，同一把锁自己套自己。这样是否会形成死锁呢？结果可能和你想像的不一样。
// 答案是，不会形成死锁。为什么不会形成死锁呢？

// 它没有用到递归的写法。DeadlockExample03中我们改成了递归的写法。
public class DeadlockExample02 {
    // 最普通的锁Object()
    private static final Object lock = new Object();

    public static void main(String[] args) {
        // 创建并启动一个线程
        Thread thread = new Thread(() -> {
            synchronized (lock) {
                System.out.println(Thread.currentThread().getName() + "获取了锁");
                // 再次尝试获取同一个锁
                synchronized (lock) {
                    System.out.println(Thread.currentThread().getName() + "再次获取了锁");
                }
            }
        });
        thread.start();
    }
}

// 后记：
// 问：为什么在一个线程里面，多次获取同一个锁不会形成死锁？
// 在这段代码中，虽然在一个线程内部两次获取了同一个锁对象 `lock`，但由于是在同一个线程内部进行的，因此不会出现死锁问题。
// 死锁通常发生在两个或多个线程之间，当每个线程都持有某个锁并且试图获取其他线程持有的锁时，可能会出现互相等待对方释放锁的情况。而在这个例子中，只有一个线程，它在自己的执行过程中两次获取了同一个锁，因此不会发生死锁。
// 虽然这段代码不会出现死锁问题，但是在实际编程中，避免在同一个线程内部多次获取同一个锁，因为这可能导致代码逻辑混乱，且容易出现其他线程争用同一锁的情况。

// 问：不是说有的锁不能重入，不能重入的锁如果重入的话，就会导致死锁问题。那上面代码中的锁如果是不可重入的锁，它应该会有死锁问题啊？
// 你是对的，如果使用的是不可重入的锁，并且在同一个线程内多次获取同一个锁，就有可能导致死锁问题。
// Java中的synchronized关键字所使用的锁是可重入的，也就是说同一个线程可以多次获取同一个锁而不会造成死锁。因此，在上面的代码中，尽管在同一个线程内部两次获取了同一个锁，但由于这是可重入的锁，所以并不会出现死锁问题。
// 如果使用了不可重入的锁，那么在同一个线程内部多次获取同一个锁，就会导致死锁问题。因为当线程已经持有锁时再次尝试获取同一锁时，会因为锁已经被当前线程持有而被阻塞，而无法释放锁，从而导致死锁。